博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
html5 图片上传,支持图片预览、压缩、及进度显示,兼容IE6+及标准浏览器
阅读量:6572 次
发布时间:2019-06-24

本文共 4469 字,大约阅读时间需要 14 分钟。

原文:

以前写过上传组件,见 ,对付一般的上传没有问题,不过如果是上传图片,且需要预览的话,就力有不逮了,趁着闲暇时间,给上传组件添加了单独的图片上传UI,支持图片预览和缩放(通过调整图片的大小以实现图片压缩)。

上传组件特点

  1. 轻量级,不依赖任何JS库,核心代码(Q.Uploader.js)仅约700行,min版本加起来不到12KB
  2. 纯JS代码,无需Flash,无需更改后台代码即可实现带进度条(IE10+、其它标准浏览器)的上传,其它(eg:IE6+)自动降级为传统方式上传
  3. 单独的图片上传UI,支持图片预览(IE6+、其它浏览器)和缩放(IE10+、其它浏览器)
  4. 上传核心与UI界面分离,可以很方便的定制上传界面包括上传按钮
  5. 上传文件的同时可以指定上传参数,支持上传类型过滤
  6. 完善的事件回调,可针对上传的每个过程进行单独处理
  7. 方便的UI接口,上传界面可以随心所欲的定制

效果如上图。由于浏览器不同,压缩效果各有不同,一个1.1MB、分辨率为 1920x1200 的图片,分辨率缩放为 1024x640 ,IE11上传后为199KB,Chrome45上传后为277KB,Firefox41上传后为360KB。

使用代码

html代码,导入样式及js上传组件,定义上传按钮及视图:

js组件调用:

var uploader = new Q.Uploader({    url: "api/upload.ashx",    target: document.getElementById("upload-target"),    view: document.getElementById("upload-view"),    //auto: false,    //图片缩放    scale: {        //要缩放的图片格式        types: ".jpg",        //最大图片大小(width|height)        maxWidth: 1024    }});//uploader.start();

一般无需更改后台代码,但如果使用了图片缩放(压缩),Firefox、Chrome 较早的版本上传后,后台可能会获取不到文件名,需要略微处理一下。以asp.net为例:

HttpRequest request = context.Request;int c = request.Files.Count;//接收上传的数据并保存到服务器for (int i = 0; i < c; i++){    HttpPostedFile file = request.Files[i];        //为兼容一些较早的浏览器,此处优先使用上传组件传递的文件名    string fileName = request["fileName"];    if (string.IsNullOrEmpty(fileName)) fileName = System.IO.Path.GetFileName(file.FileName);    string path = context.Server.MapPath("~/upload/" + fileName);    file.SaveAs(path);}

 

关于上传

参见  

关于预览

IE10+等浏览器使用html5 api,其它浏览器使用滤镜预览。需要注意的是,IE8+由于安全性考虑,会获取不到文件真实地址,需要特殊处理一下。

//生成图片预览地址(html5)function readAsURL(file, callback) {    var URL = window.URL || window.webkitURL;    if (URL) return callback(URL.createObjectURL(file));    if (window.FileReader) {        var fr = new FileReader();        fr.onload = function (e) {            callback(e.target.result);        };        fr.readAsDataURL(file);    } else if (file.readAsDataURL) {        callback(file.readAsDataURL());    }}//图片预览function previewImage(box, task, callback) {    var input = task.input,        file = task.file || (input.files ? input.files[0] : undefined);    if (file) {        //IE10+、Webkit、Firefox etc        readAsURL(file, function (src) {            if (src) box.innerHTML = '';            callback && callback(src);        });    } else if (input) {        var src = input.value;        if (!src || /^\w:\\fakepath/.test(src)) {            input.select();            //解决ie报拒绝访问的问题            parent.document.body.focus();            //获取图片真实地址            if (document.selection) src = document.selection.createRange().text;        }        if (src) {            box.innerHTML = '';            try {                if (browser_ie > 6) box.style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(sizingMethod='scale',src='" + src + "')";            } catch (e) { }        }        callback && callback(src);    }}

关于缩放(压缩)

原理是先通过canvas调整图片大小,生成base64数据,然后再通过html5 api (Blob) 转换为二进制对象上传。

//将dataURL转为Blob对象,以用于ajax上传function dataURLtoBlob(base64, mimetype) {    var ds = base64.split(','),        data = atob(ds[1]),        arr = [];    for (var i = 0, len = data.length; i < len; i++) {        arr[i] = data.charCodeAt(i);    }    if (Blob) return new Blob([new Uint8Array(arr)], { type: mimetype });    var builder = new BlobBuilder();    builder.append(arr);    return builder.getBlob(mimetype);}//图片缩放function scaleImage(src, mimetype, ops, callback) {    var image = new Image();    image.src = src;    image.onload = function () {        var width = image.width,            height = image.height,            maxWidth = ops.maxWidth,            maxHeight = ops.maxHeight,            hasWidthScale = maxWidth && width > maxWidth,            hasHeightScale = maxHeight && height > maxHeight,            hasScale = hasWidthScale || hasHeightScale;        //无需压缩        if (!hasScale) return callback && callback(false);        //根据宽度缩放        if (hasWidthScale) {            width = maxWidth;            height = Math.floor(image.height * width / image.width);        }        //根据高度缩放        if (hasHeightScale) {            height = maxHeight;            width = Math.floor(image.width * height / image.height);        }        var canvas = document.createElement("canvas"),            ctx = canvas.getContext("2d");        canvas.width = width;        canvas.height = height;        ctx.drawImage(image, 0, 0, width, height);        callback && callback(canvas.toDataURL(mimetype), mimetype);    };}

 

其它参见源码及示例代码。

代码下载

写在最后

如果本文或本项目对您有帮助的话,请不吝点个赞。欢迎交流!

转载地址:http://ievjo.baihongyu.com/

你可能感兴趣的文章
设计模式C++学习笔记之三(Singleton单例模式)
查看>>
【Oracle学习笔记-4】内连接和外连接的区别
查看>>
CSS初始化示例代码
查看>>
管道的故事(转)
查看>>
基于jquery响应式网站图片无限加载瀑布流布局
查看>>
关于开源的金玉良言
查看>>
Library Cache: Lock, Pin and Load Lock
查看>>
python查询mysql中文乱码问题
查看>>
JellyViewPager
查看>>
Linux守护进程的编程实现
查看>>
深入PHP内核之ZVAL
查看>>
T3 - 构建大型 Web 应用的 JavaScript 框架
查看>>
【书评:Oracle查询优化改写】第三章
查看>>
错误代码:ERR_UNSAFE_PORT
查看>>
Android中Parcelable与Serializable接口用法
查看>>
【angularjs】【学习心得】路由继续研究篇
查看>>
装饰模式
查看>>
LESS CSS 框架简介(转)
查看>>
Partition List -- LeetCode
查看>>
探秘腾讯Android手机游戏平台之不安装游戏APK直接启动法
查看>>